package rsshelp

import (
	"fmt"
	"gitee.com/captials-team/ubdframe/src/domain/vo"
	v1log "gitee.com/captials-team/ubdframe/src/pkg/logs"
	"io"
	"net/http"
	"os"
	"time"
)

type RssFetcher struct {
	l        v1log.ILog
	rssMap   map[string]*vo.RssMeta
	client   *http.Client
	handlers []RssHandler
}

type RssHandler func(meta *vo.RssMeta, body *vo.RssBody)

func NewRssFetcher(l v1log.ILog) *RssFetcher {
	if l == nil {
		l = v1log.NewWriterLog(os.Stdout, v1log.DebugLog)
	}
	return &RssFetcher{
		client: &http.Client{Timeout: time.Second * 5},
		rssMap: map[string]*vo.RssMeta{},
		l:      l,
	}
}

func (w *RssFetcher) AddRssMeta(meta ...*vo.RssMeta) {
	for _, v := range meta {
		w.rssMap[v.Name] = v
	}
}

func (w *RssFetcher) AddRss(name, url string) {
	w.rssMap[name] = &vo.RssMeta{
		Name:   name,
		RssUrl: url,
	}
}

func (w *RssFetcher) AddHandler(h RssHandler) {
	w.handlers = append(w.handlers, h)
}

// runPullRss 拉取rss
func (w *RssFetcher) runPullRss(meta *vo.RssMeta, handlers ...RssHandler) error {
	w.l.Info("rss pull running: %+v", meta)
	var err error

	resp, err := w.client.Get(meta.RssUrl)
	if err != nil {
		return err
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("request code is %d", resp.StatusCode)
	}

	//解析rss
	rss, err := w.parseRss(resp.Body)
	if err != nil {
		return err
	}

	//logger.Infof("%s", rss.Channel.Title)
	//logger.Infof("%s", rss.Channel.Link)
	//logger.Infof("%s", rss.Channel.PubDate)

	//对结果调用handler
	for _, h := range handlers {
		h(meta, rss)
	}

	return nil
}

func (w *RssFetcher) Fetch() {
	w.FetchHandler(w.handlers...)
}

// FetchHandler 顺序拉取
func (w *RssFetcher) FetchHandler(handlers ...RssHandler) {
	for _, v := range w.rssMap {
		var meta = *v

		err := w.runPullRss(&meta, handlers...)
		if err != nil {
			w.l.Error("run pull fail %s,%+v", err, meta)
		}
	}
}

func (w *RssFetcher) parseRss(r io.Reader) (*vo.RssBody, error) {
	rss := &vo.RssBody{}
	err := rss.Parse(r)
	if err != nil {
		return rss, err
	}

	return rss, nil
}
